use regex::Regex;
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

use crate::helper::{build_regex, extract_combined_index, extract_data};

/// 内存信息
#[derive(Debug, Serialize, Deserialize, Default, JsonSchema, Clone)]
pub struct Memory {
    /// 内存分类
    ///
    /// Byte
    ///
    /// 1.3.6.1.4.1.9.9.48.1.1.1.2
    ///
    /// iso.3.6.1.4.1.9.9.48.1.1.1.2.1 = STRING: "Processor"
    ///
    /// iso.3.6.1.4.1.9.9.48.1.1.1.2.11 = STRING: "reserve Processor"
    pub memory_name: String,

    /// Memory 使用
    ///
    /// Byte
    ///
    ///   1.3.6.1.4.1.9.9.48.1.1.1.5
    ///
    /// iso.3.6.1.4.1.9.9.48.1.1.1.5.1 = Gauge32: 268704008
    ///
    /// iso.3.6.1.4.1.9.9.48.1.1.1.5.11 = Gauge32: 88
    pub memory_used: String,

    ///总内存
    ///
    /// byte
    ///
    /// 1.3.6.1.4.1.28557.2.2.1.4
    ///
    /// iso.3.6.1.4.1.28557.2.2.1.4.0 = Gauge32: 8991744
    pub total_memory: String,

    /// 当前使用内存
    ///
    /// Byte
    ///
    /// 1.3.6.1.4.1.28557.2.2.1.5
    ///
    /// iso.3.6.1.4.1.28557.2.2.1.5.0 = Gauge32: 729429
    pub current_memory: String,

    /// Memory 空闲
    ///
    /// Byte
    ///
    /// 1.3.6.1.4.1.9.9.48.1.1.1.6
    ///
    /// iso.3.6.1.4.1.9.9.48.1.1.1.6.1 = Gauge32: 1107392536
    ///
    /// iso.3.6.1.4.1.9.9.48.1.1.1.6.11 = Gauge32: 102316
    pub memory_free: String,

    /// 内存使用率
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.7
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.7.335544321 = INTEGER: 0
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.7.603979777 = INTEGER: 28
    pub mem_usage_percent: String,

    /// 内存使用阈值
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.8
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.8.335544321 = INTEGER: 0
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.8.603979777 = INTEGER: 95
    pub mem_usage_threshold: String,

    /// 内存大小
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.9
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.9.335544321 = INTEGER: 0
    ///
    /// iso.3.6.1.4.1.2011.5.25.31.1.1.1.1.9.603979777 = INTEGER: 20051704
    pub mem_size: String,
}

impl Memory {
    pub fn values(text: &str) -> Vec<Self> {
        let re = Regex::new(r".3.6.1.4.1.9.9.48.1.1.1.2.(\d+)").unwrap();
        let mut memories = vec![];
        for cap in re.captures_iter(text) {
            let index = &cap[1];
            memories.push(Memory {
                memory_name: extract_combined_index(
                    ".3.6.1.4.1.9.9.48.1.1.1.2.",
                    index,
                    r#" = STRING: "(.+)""#,
                    text,
                ),
                memory_used: extract_combined_index(
                    ".3.6.1.4.1.9.9.48.1.1.1.5.",
                    index,
                    r#" = Gauge32: (\d+)"#,
                    text,
                ),
                memory_free: extract_combined_index(
                    ".3.6.1.4.1.9.9.48.1.1.1.6.",
                    index,
                    r#" = Gauge32: (\d+)"#,
                    text,
                ),
                total_memory: extract_data(r".3.6.1.4.1.28557.2.2.1.4.0 = Gauge32: (\d+)", text),

                current_memory: extract_data(r"3.6.1.4.1.28557.2.2.1.5.0 = Gauge32: (\d+)", text),
                ..Default::default()
            })
        }
        let re = build_regex(r"3.6.1.4.1.2011.5.25.31.1.1.1.1.5.(\d+)");
        for cap in re.captures_iter(text) {
            let index = &cap[1];
            memories.push(Memory {
                mem_usage_percent: extract_combined_index(
                    "3.6.1.4.1.2011.5.25.31.1.1.1.1.7.",
                    index,
                    r" = INTEGER: (\d+)",
                    text,
                ),
                mem_usage_threshold: extract_combined_index(
                    ".3.6.1.4.1.2011.5.25.31.1.1.1.1.8.",
                    index,
                    r" = INTEGER: (\d+)",
                    text,
                ),
                mem_size: extract_combined_index(
                    ".3.6.1.4.1.2011.5.25.31.1.1.1.1.9.",
                    index,
                    r" = INTEGER: (\d+)",
                    text,
                ),
                ..Default::default()
            })
        }

        memories
    }
}
